{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd\n",
    "from sklearn.model_selection import cross_val_score,GridSearchCV,cross_val_predict\n",
    "from sklearn.metrics import precision_score,recall_score,confusion_matrix\n",
    "from sklearn.datasets import fetch_mldata\n",
    "from scipy.ndimage.interpolation import shift\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def shift_img(img,dx,dy):\n",
    "    img = img.reshape(28,28)\n",
    "    shifted_img = shift(img,[dy,dx])\n",
    "    return shifted_img.reshape(-1)\n",
    "def show_shifted_img(X,i,dx,dy):\n",
    "    some_digit = X[i]\n",
    "    some_digit_shifted = shift_img(some_digit,dx,dy).reshape(28,28)\n",
    "    plt.imshow(some_digit_shifted,cmap=matplotlib.cm.binary\n",
    "               ,interpolation='nearest')\n",
    "    plt.show()\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "mnist = fetch_mldata('MNIST original',data_home='./')\n",
    "X = mnist['data']\n",
    "y = mnist['target']\n",
    "X_train,X_test,y_train,y_test = X[:60000],X[60000:],y[:60000],y[60000:]\n",
    "np.random.seed(42)\n",
    "nrp = np.random.permutation(60000)\n",
    "X_train = X_train[nrp]\n",
    "y_train = y_train[nrp]\n",
    "y_train_6 = (y_train==6)\n",
    "y_test_6 = (y_test==6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train_shifted = []\n",
    "y_tarin_shifted = []\n",
    "for img,label in zip(X_train,y_train):\n",
    "    for dx,dy in [[1,0],[0,1],[-1,0],[0,-1]]:\n",
    "        X_train_shifted.append(shift_img(img,dx,dy))\n",
    "        y_tarin_shifted.append(label)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(240000, 784)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train_shifted = np.array(X_train_shifted)\n",
    "X_train_shifted.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(240000,)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_tarin_shifted = np.array(y_tarin_shifted)\n",
    "y_tarin_shifted.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=1, n_neighbors=5, p=2,\n",
       "           weights='uniform')"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_shifted_6 = (y_tarin_shifted==6)\n",
    "knn_clf = KNeighborsClassifier()\n",
    "knn_clf.fit(X_train_shifted,y_train_shifted_6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cross_val_score(knn_clf,X_train_shifted,y_train_shifted_6,cv=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train_predict = cross_val_predict(knn_clf,X_train_shifted,y_train_shifted_6,cv=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "confusion_matrix(y_tarin_shifted_6,y_train_predict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "precision_score(y_tarin_shifted_6,y_train_predict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "recall_score(y_tarin_shifted_6,y_train_predict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_test_predict = knn_clf.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_test_ca_predict = cross_val_predict(knn_clf,X_test,y_test_6,cv=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "confusion_matrix(y_test_6,y_test_ca_predict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "precision_score(y_test_6,y_test_ca_predict)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "recall_score(y_test_6,y_test_ca_predict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 网格搜索"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "param_grid = [{'weights':['uniform','distance'],'n_neighbors':[2,4,6]}]\n",
    "knn_clf = KNeighborsClassifier()\n",
    "grid_search = GridSearchCV(knn_clf,param_grid,cv=3,verbose=3)\n",
    "grid_search.fit(X_train_shifted,y_train_predict_6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_grid_test_predict = grid_search.predict(X_test_6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_grid_test_pred = cross_val_predict(grid_search,X_test,y_test_6,cv=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "confusion_matrix(y_test_6,y_grid_test_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "precision_score(y_test_6,y_grid_test_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "recall_score(y_test_6,y_grid_test_pred)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
